package com.ahp.service.impl;

import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.struts2.ServletActionContext;

import com.ahp.bean.EvaleObject;
import com.ahp.bean.Factor;
import com.ahp.bean.Module;
import com.ahp.bean.Tast;
import com.ahp.bean.User;
import com.ahp.dao.EvaleObjectDao;
import com.ahp.dao.FactorDao;
import com.ahp.dao.ModuleDao;
import com.ahp.dao.TaskDao;
import com.ahp.service.EvaleObjectService;
import com.ahp.service.ModuleService;
import com.ahp.util.PageList;
import com.ahp.util.Pages;
import com.ahp.util.WirteFile;

public class ModuleServiceImpl implements ModuleService {
	private ModuleDao moduleDao;
	private FactorDao factorDao;
	private TaskDao taskDao;
	private EvaleObjectDao evaleObjectDao;

	public EvaleObjectDao getEvaleObjectDao() {
		return evaleObjectDao;
	}

	public void setEvaleObjectDao(EvaleObjectDao evaleObjectDao) {
		this.evaleObjectDao = evaleObjectDao;
	}

	public ModuleDao getModuleDao() {
		return moduleDao;
	}

	public void setModuleDao(ModuleDao moduleDao) {
		this.moduleDao = moduleDao;
	}
	
	public FactorDao getFactorDao() {
		return factorDao;
	}

	public void setFactorDao(FactorDao factorDao) {
		this.factorDao = factorDao;
	}

	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#searchDefaultAndMineModule(com.ahp.bean.User)
	 */
	public List<Module> searchDefaultAndMineModule(User user) {
		String hql = "from Module mod where mod.type=? or mod.user.id=?";
		return moduleDao.queryInfo(hql, Module.TYPE_MODULE_DEFAULT, user.getId());
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#searchDefaultAndMineModule(com.ahp.bean.User)
	 */
	public PageList searchUserModule(User user,Pages pages) {
		return  moduleDao.moduleList(user, pages);
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseModule(java.util.List)
	 */
	public Map<String,Map<Integer,Set<Factor>>> parseModule(List<Module> list) {
		//<mod,Map<lev1,Set<Factor>>>
		Map<String,Map<Integer,Set<Factor>>> modMap = new HashMap<String,Map<Integer,Set<Factor>>>();
		for (Module module : list) {
			Map<Integer,Set<Factor>> lev1Map = new HashMap<Integer,Set<Factor>>();
			module = (Module)moduleDao.get(Module.class, module.getModId());
			Set<Factor> factors = module.getFactors();
			Set<Factor> facLev1 = new HashSet<Factor>();
			
			//分离一级因子
			for (Factor factor2 : factors) {
				if(factor2.getLevel() == 1){
					facLev1.add(factor2);
				}
			}
			//由一级节点获取二级节点
			for (Factor factor3 : facLev1) {
				Set<Factor> facLev2 = new HashSet<Factor>();
				for (Factor fac : factors) {
					if(fac.getPid().equals(factor3.getFacId())){
						facLev2.add(fac);
					}
				}
				lev1Map.put(factor3.getFacId(), facLev2);
			}
			modMap.put("mod"+module.getModId(), lev1Map);
		}
		return modMap;
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseModule(java.lang.Integer)
	 */
	public Map<Integer,Set<Factor>> parseModule(Integer moduleId){
		Map<Integer,Set<Factor>> lev1Map = new HashMap<Integer,Set<Factor>>();
		Module module = (Module)moduleDao.get(Module.class, moduleId);
		Set<Factor> factors = module.getFactors();
		Set<Factor> facLev1 = new HashSet<Factor>();
		
		//分离一级因子
		for (Factor factor2 : factors) {
			if(factor2.getLevel() == 1){
				facLev1.add(factor2);
			}
		}
		//由一级节点获取二级节点
		for (Factor factor3 : facLev1) {
			Set<Factor> facLev2 = new HashSet<Factor>();
			for (Factor fac : factors) {
				if(fac.getPid().equals(factor3.getFacId())){
					facLev2.add(fac);
				}
			}
			lev1Map.put(factor3.getFacId(), facLev2);
		}
		return lev1Map;
	}

	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseModuleGetLevelOne(java.lang.Integer)
	 */
	public List<Factor> parseModuleGetOneLevel(Integer moduleId, Integer level) {
		String hql = "from Factor f where f.module.modId=? and f.level=?";
		return factorDao.queryInfo(hql, moduleId, level);
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseLevelOne(java.util.Map)
	 */
	public List<String[]> parseLevelOne(Map<String, String[]> map) {
		Map session = ServletActionContext.getContext().getSession();
		List<String[]> list = new ArrayList<String[]>();
		List<String> parseLevelOneResult = new ArrayList<String>();
		String[] arr = null;
		for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
			arr = new String[2];
			String key = it.next();
			if(key.startsWith("id-", 0)){
				arr[0] = key.split("-")[1];
				arr[1] = map.get(key)[0];
				list.add(arr);
				parseLevelOneResult.add(arr[1]);
				session.put("parseLevelOneResult",parseLevelOneResult);
			}
		}
		return list;
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseOneTwoLevelFactor(java.util.List, java.util.List)
	 */
	public Map<Integer,List<Factor>> parseOneTwoLevelFactor(List<Factor> levelOne, List<Factor> levelTwo){
		Map<Integer,List<Factor>> map = new HashMap<Integer, List<Factor>>();
		for (Factor one : levelOne) {
			List<Factor> setTwo = new ArrayList<Factor>();
			for (Factor two : levelTwo) {
				if(one.getFacId().equals( two.getPid() )){
					setTwo.add(two);
				}
			}
			map.put(one.getFacId(), setTwo);
		}
		return map;
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseLevelTwo(java.util.Map, java.util.List)
	 */
	public Map<String,Float> parseLevelTwo(Map<String, String[]> map, List<String[]> levOneList) {
		Map session = ServletActionContext.getContext().getSession();
		List<String> parseLevelTwoResult = new ArrayList<String>();
		//一级因子id,权重
		Map<String, Float> levOneMap = new HashMap<String, Float>();
		for (String[] strs : levOneList) {
			levOneMap.put(strs[0], Float.parseFloat(strs[1])) ;
		}
		String[] arr = null;
		//一级因子，所有二级,因子id,权重
		Map<String,Set<String[]>> paramMap = new HashMap<String, Set<String[]>>();
		for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
			arr = new String[3];
			String key = it.next();
			if(key.startsWith("id-", 0)){
				arr = key.split("-");
				String value = map.get(key)[0];
				parseLevelTwoResult.add(value);
				session.put("parseLevelTwoResult",parseLevelTwoResult);
					System.out.println("value::::"+value);
				if(paramMap.containsKey(arr[1])){
					Set<String[]> set = paramMap.get(arr[1]);
					String[] strs = new String[2];
					strs[0] = arr[2];
					strs[1] = value;
					set.add(strs);
				}else{
					String [] strs = new String[2];
					strs[0] = arr[2];
					strs[1] = value;
					Set<String[]> set = new HashSet<String[]>();
					set.add(strs);
					paramMap.put(arr[1], set);
				}
			}
		}

		//二级因子id，乘积
		Map<String,Float> mult = new HashMap<String, Float>();
		for(Iterator<String> it = levOneMap.keySet().iterator(); it.hasNext();){
			String oneKey = it.next();
			Float oneVal = levOneMap.get(oneKey);
			Set<String[]> facs = paramMap.get(oneKey);
			for (String[] strs : facs) {
				Float mul = oneVal * Float.parseFloat(strs[1]) / 10000;
				mult.put(strs[0], mul);
			}
		}
		
		return mult;
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#parseLevelTwo(java.util.Map)
	 */
	public Map<String,Set<String[]>> parseLevelTwo(Map<String, String[]> map ) {
		Map session = ServletActionContext.getContext().getSession();
		List<String> parseLevelTwoResult = new ArrayList<String>();
		String[] arr = null;
		Set<String> sizeRule = new HashSet<String>();
		for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
			arr = new String[3];
			String key = it.next();
			if(key.startsWith("id-", 0)){
				arr = key.split("-");
				String evaleObject = arr[1];
				if(!sizeRule.contains(evaleObject)){
					sizeRule.add(evaleObject);
				}
			}
		}
		//不同对象中因子值
		Map<String,Set<String[]>> list = new HashMap<String,Set<String[]>>();
		Set<String[]> set = null;
		for (String string : sizeRule) {
			set = new HashSet<String[]>(); 
			String objectId = null;
			for(Iterator<String> it = map.keySet().iterator(); it.hasNext();){
				arr = new String[3];
				String key = it.next();
				if(key.startsWith("id-", 0)){
					arr = key.split("-");
					String value = map.get(key)[0];
					parseLevelTwoResult.add("value:"+value);
					session.put("parseFinalResult", parseLevelTwoResult);
					String evaleObject = arr[1];
					String factorId = arr[2];
					if(string.equals(evaleObject)){
						objectId = evaleObject;
						set.add(new String[]{factorId,value});
					}
				}
			}
			list.put(objectId, set);
		}
		this.write();
		return list;
	}
	
	/* (non-Javadoc)
	 * @see com.ahp.service.ModuleService#ahp(java.util.Map, java.util.Map)
	 */
	public Map<String, Float> ahp(Map<String,Set<String[]>> map1, Map<String, Float> map2) {
		Map<String, Float> map = new LinkedHashMap<String, Float>();
		Set<String> evaleObjectSet = map1.keySet();
		for(Iterator<String> it = evaleObjectSet.iterator(); it.hasNext();){
			String objectId = it.next();
			Set<String[]> set = map1.get(objectId);
			Float mult = 0f;
			for (String[] strings : set) {
				Float one = map2.get(strings[0]);
				Float two = Float.parseFloat(strings[1]);
				mult += one*two/100;
			}
			map.put(objectId, mult);
		}
		
		return map;
	}
	
	public boolean addModule(Module mod){
		return moduleDao.addModule(mod);
	}
	
	public void write(){
		WirteFile wf = new WirteFile();
		StringBuffer sb = new StringBuffer();
		Map session = ServletActionContext.getContext().getSession();
		List<String> one = (List)session.get("parseLevelOneResult");
		List<String> two = (List)session.get("parseLevelTwoResult");
		Map<String,String[]>  fin =(Map)session.get("ahpResult");
		Tast tast = taskDao.load((Integer)session.get("task"));
		
		int modID = Integer.valueOf(session.get(Module.SESSION_MODULE).toString());
		Module module = moduleDao.load(Module.class, modID);
		
		sb.append("任务名称:"+tast.getName()+"\r\n");
		sb.append("评估描述："+tast.getDescription()+"\r\n");
		sb.append("模板名称："+module.getName()+"\r\n");
		
		List<Factor> firstFactor =  factorDao.findFirstFactor(modID);
		sb.append("一级因子权重:\r\n");
		for(int a = 0 ; a<firstFactor.size();a++){
			for(int b = 0;b<=a;b++){
				sb.append(firstFactor.get(0).getName()+":"+one.get(b).toString());
			}
		}
		sb.append("\r\n二级因子权重:\r\n");
		for(int a = 0 ; a<firstFactor.size();a++){
				List<Factor> secondFactor= factorDao.findSecondFactor(firstFactor.get(a).getFacId());
				sb.append(firstFactor.get(a).getName()+":\r\n");
				for(int c = 0;c<secondFactor.size();c++){
					for(int d = 0;d<=c;d++){
						sb.append(secondFactor.get(c).getName()+":"+two.get(d).toString()+"\r\n");
					}
				}
		}
		
		List<EvaleObject> evaleObjectList = this.findEvaleObject(tast.getTastId());
		for(int e = 0;e<evaleObjectList.size();e++){
			sb.append("         "+evaleObjectList.get(e).getName()+"   ");
		}
			sb.append("\r\n");
			List<Factor> secondFactor = factorDao.SecondFactor(modID);
			for(int s = 0;s<secondFactor.size();s++){
					sb.append(secondFactor.get(s).getName()+":");
					for(int u = 0;u<evaleObjectList.size();u++){
						boolean b = true;
						if(b){
						for (Iterator<String> iterator = fin.keySet().iterator(); iterator.hasNext();) {
							String key = iterator.next();
							String [] k = key.split("-");
							String value = fin.get(key)[0];
							if(String.valueOf(secondFactor.get(s).getFacId()).equals(k[2])
									&& String.valueOf(evaleObjectList.get(u).getEvaleId()).equals(k[1])){
								sb.append("  "+value+"  ");
								 b = false;
							}
						  }
						}
					}
					sb.append("\r\n");
			}
		String filename =  this.getDateTime();
		System.out.println(this.getRealPath());
		this.create(sb.toString(),filename);
		tast.setFileName(filename+".txt");
		taskDao.update(taskDao.get(Tast.class, tast.getTastId()));
	}
	
	public List<EvaleObject> findEvaleObject(Integer id) {
		String hql = "from EvaleObject eo where eo.tast.tastId=?";
		return evaleObjectDao.queryInfo(hql, id);
	}
	
	
	public static String getDateTime() {
		StringBuffer uploadTime = new StringBuffer();
		Calendar c = new GregorianCalendar();
		uploadTime.append(Integer.valueOf(c.get(Calendar.YEAR)).toString()); // 年
		uploadTime.append(c.get(Calendar.MONTH) + 1); // 月
		uploadTime.append(Integer.valueOf(c.get(Calendar.DAY_OF_MONTH)).toString()); // 日
		uploadTime.append(Integer.valueOf(c.get(Calendar.HOUR_OF_DAY)).toString()); // 时
		uploadTime.append(Integer.valueOf(c.get(Calendar.MINUTE)).toString()); // 分
		uploadTime.append(Integer.valueOf(c.get(Calendar.SECOND)).toString()); // 秒
		uploadTime.append(Integer.valueOf(c.get(Calendar.MILLISECOND)).toString()); // 毫秒
		return uploadTime.toString();
	}// end method

	public TaskDao getTaskDao() {
		return taskDao;
	}

	public void setTaskDao(TaskDao taskDao) {
		this.taskDao = taskDao;
	}

	public boolean create(String content,String fileName){
		boolean b = false;
		try {
			File f = new File(this.getRealPath()+"\\file\\"+fileName+".txt");
			if(f.isFile()){
				System.out.println("文件已存在");
			}else{
				f.createNewFile();
				System.out.println("文件创建成功");
			}
			PrintWriter printwriter = new PrintWriter(f);
			printwriter.print(content);
			printwriter.close();
			b = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return b;
	}
 
	private String getRealPath(){
		return ServletActionContext.getRequest().getSession().getServletContext().getRealPath("/");
	}
}
